package cn.legym.garp.gateway.traffic.param;

import cn.legym.garp.gateway.traffic.ParamSourceParser;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.ResolvableType;
import org.springframework.core.codec.ByteArrayDecoder;
import org.springframework.http.codec.DecoderHttpMessageReader;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * create by pipisun on 2021/9/6
 * copyright © 2017-2021 Legym Technology Co.,Ltd. All rights reserve
 * d.
 * file description:
 * last update by {} on {}
 * update description:
 */
@Slf4j
@Component
public class RequestBodyParamParser implements ParamSourceParser {
    private static final ObjectMapper mapper = new ObjectMapper();
    private static final JavaType map_type = mapper.getTypeFactory().constructMapType(HashMap.class, String.class, String.class);

    @Override
    public String parse(ServerHttpRequest request, String key) {
        try {
            DecoderHttpMessageReader<byte[]> httpMessageReader = new DecoderHttpMessageReader<>(new ByteArrayDecoder());
            ResolvableType resolvableType = ResolvableType.forClass(byte[].class);
            Mono<byte[]> mono = httpMessageReader.readMono(resolvableType, request, Collections.emptyMap());
            String body = mono.map(String::new).block(Duration.ofMillis(1000));
            Map<String, String> map = mapper.readValue(body, map_type);
            return map.get(key);
        } catch (Exception e) {
            log.error("", e);
        }
        return null;
    }
}
